using System.Collections.Generic;
using NHibernate.Criterion;

namespace Project.Library.NHibernate
{
    public interface INHibernateRepository<T, idT>
    {
        /// <summary>
        /// Existses the specified criteria.
        /// </summary>
        /// <param name="criteria">The criteria.</param>
        /// <returns></returns>
        bool Exists(DetachedCriteria criteria);

        /// <summary>
        /// Counts the specified criteria.
        /// </summary>
        /// <param name="criteria">The criteria.</param>
        /// <returns></returns>
        long Count(DetachedCriteria criteria);

        /// <summary>
        /// Creates the detached criteria.
        /// </summary>
        /// <returns></returns>
        DetachedCriteria CreateDetachedCriteria();

        /// <summary>
        /// Creates the detached criteria.
        /// </summary>
        /// <param name="alias">The alias.</param>
        /// <returns></returns>
        DetachedCriteria CreateDetachedCriteria(string alias);

        /// <summary>
        /// Gets the specified id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        T Get(idT id);

        /// <summary>
        /// Finds the entities that match the criteria.
        /// </summary>
        /// <param name="criteria">The criteria.</param>
        /// <returns></returns>
        IEnumerable<T> FindAll(DetachedCriteria criteria);

        /// <summary>
        /// Finds the entities that match the criteria and order the result.
        /// </summary>
        /// <param name="criteria">The criteria.</param>
        /// <param name="orders">The orders.</param>
        /// <returns></returns>
        IEnumerable<T> FindAll(DetachedCriteria criteria, params Order[] orders);

        /// <summary>
        /// Finds the entities that match the criteria and order the result.
        /// Gives support for paging
        /// </summary>
        /// <param name="criteria">The criteria.</param>
        /// <param name="firstResult">The first result.</param>
        /// <param name="maxResult">The max result.</param>
        /// <param name="orders">The orders.</param>
        /// <returns></returns>
        IEnumerable<T> FindAll(DetachedCriteria criteria, int firstResult, int maxResult, params Order[] orders);

        /// <summary>
        /// Finds the result that match the criteria.
        /// Throw an exception if more than one entity matches the criteria
        /// </summary>
        /// <param name="criteria">The criteria.</param>
        /// <returns></returns>
        T FindOne(DetachedCriteria criteria);

        /// <summary>
        /// Finds the first result that match the criteria.
        /// Returns null if no entity matches the criteria
        /// </summary>
        /// <param name="criteria">The criteria.</param>
        /// <returns></returns>
        T FindFirst(DetachedCriteria criteria);

        /// <summary>
        /// Finds the first.
        /// </summary>
        /// <param name="criteria">The criteria.</param>
        /// <param name="orders">The orders.</param>
        /// <returns></returns>
        T FindFirst(DetachedCriteria criteria, params Order[] orders);

        /// <summary>
        /// Saves the or update.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns></returns>
        T SaveOrUpdate(T entity);

        /// <summary>
        /// Saves the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns></returns>
        T Save(T entity);

        /// <summary>
        /// Updates the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns></returns>
        T Update(T entity);

        /// <summary>
        /// Deletes the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        void Delete(T entity);

        /// <summary>
        /// Deletes the specified criteria.
        /// </summary>
        /// <param name="criteria">The criteria.</param>
        void Delete(DetachedCriteria criteria);
    }
}